/**
 * file :	lpool.h
 * author :	bushaofeng
 * created :	2013-04-08 00:10
 * func :       链表pool
 */

#ifndef	__LPOOL_H_
#define	__LPOOL_H_


#define LPOOL_DEF_SIZE  10240
template <typename T>
class LPool{
    private:
        typedef struct{
            T   item;
            T*  prev;
            T*  next;
        }_pool_item_t;

    public:
        LPool(size_t size = MPOOL_DEF_SIZE){
            m_list = new _pool_iterm_t[size];
            assert(m_list);
            assert(pthread_rwlock_init(&m_lock, NULL)==0);
            m_unused->next = &m_list[0];
            m_list[0].prev = &m_unused;
            for(int i=0;i<size-1;i++){
                m_list[i].next = &m_list[i+1];
                m_list[i+1].prev = &m_list[i];
            }
            m_list[size-1].next = NULL;
            m_used.next = NULL;
        }

        ~LPool(){
            delete[] m_list;
            pthread_rwlock_destroy(&m_lock);
        }

        bool del(T* p){
            pthread_rwlock_wrlock(&m_lock);
            if(!(p>m_list && p<m_list+m_size)){
                return false;
            }
            pthread_rwlock_unlock(&m_lock);
        }

        T* pop(){
            pthread_rwlock_wrlock(&m_lock);
            T* t = NULL;
            if(m_unused.next){
                t = m_unused.next;
                m_unused.next = t->next;
                if(t->next){
                    t->next->prev = t->prev;
                }
                t->next = m_used->next;
                t->prev = &m_used;
                if(t->next){
                    t->next->prev = t;
                }
                m_used->next = t;
            }
            pthread_rwlock_unlock(&m_lock);
            return t;
        }

        size_t length(){return m_length;}
        size_t size(){return m_size;}

    private:
        _pool_item_t*           m_list;
        _pool_item_t            m_unused;
        _pool_item_t            m_used;
        pthread_rwlock_t        m_lock;
        size_t                  m_size;
        size_t                  m_length;
};

#endif
